﻿using Microsoft.EntityFrameworkCore;
using RotovapPlatform.Domain.Business.Storage.Entities;
using RotovapPlatform.Domain.Business.Storage.Entities.Base;
using RotovapPlatform.Domain.Business.Storage.Entities.Bottles;
using RotovapPlatform.Infrastructure.Common.Json;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Unicode;
using static RotovapPlatform.Domain.Business.Machine.Enums.ExperimentConfigEnums;

namespace RotovapPlatform.Infrastructure.Common.Data;

/// <summary>
/// 存储位置数据库上下文
/// 负责管理仓储位置和瓶子信息的数据访问和持久化
/// </summary>
public class StorageDbContext : DbContext
{
	/// <summary>
	/// 存储位置数据集
	/// 用于访问和管理仓储位置数据
	/// </summary>
	public DbSet<StorageLocation> StorageLocations { get; set; }

	/// <summary>
	/// 构造函数
	/// </summary>
	/// <param name="options">数据库上下文配置选项</param>
	public StorageDbContext(DbContextOptions<StorageDbContext> options) : base(options)
	{
	}

	/// <summary>
	/// 配置实体模型
	/// </summary>
	/// <param name="modelBuilder">模型构建器</param>
	protected override void OnModelCreating(ModelBuilder modelBuilder)
	{
		modelBuilder.Entity<StorageLocation>(entity =>
		{
			// 配置主键
			entity.HasKey(e => e.Id);
			// 设置位置代号和具体位置的唯一索引
			entity.HasIndex(e => new { e.LocationCode, e.Position }).IsUnique();

			// 配置 JSON 序列化选项，支持中文编码
			var jsonOptions = new JsonSerializerOptions
			{
				Encoder = JavaScriptEncoder.Create(UnicodeRanges.All),
				WriteIndented = true
			};

			// 添加自定义转换器
			jsonOptions.Converters.Add(new StorageItemJsonConverter());

			// 配置支持的物品类型列表的 JSON 转换
			entity.Property(e => e.SupportedItemTypes)
				.HasConversion(
					v => JsonSerializer.Serialize(v, jsonOptions),
					v => JsonSerializer.Deserialize<List<ItemType>>(v, jsonOptions)!
				);

			// 配置当前存储物品的 JSON 转换
			entity.Property(e => e.CurrentItem)
				.HasConversion(
					v => v != null ? JsonSerializer.Serialize(v, jsonOptions) : null,
					v => v != null ? JsonSerializer.Deserialize<IStorageItem>(v, jsonOptions)! : null
				);
		});
	}

	/// <summary>
	/// 配置数据库连接
	/// </summary>
	/// <param name="optionsBuilder">数据库配置构建器</param>
	protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
	{
		if (!optionsBuilder.IsConfigured)
		{
			// 配置 SQLite 数据库连接和查询分割行为
			optionsBuilder.UseSqlite("Data Source=Rotovap.db",
				options => options.UseQuerySplittingBehavior(QuerySplittingBehavior.SplitQuery));
		}

		// 确保使用 UTF-8 编码的 SQLite 提供程序
		SQLitePCL.raw.SetProvider(new SQLitePCL.SQLite3Provider_e_sqlite3());
	}
}